home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / editors / mjovesrc.zoo / fp.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  7KB  |  361 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "fp.h"
  10. #include "ctype.h"
  11. #include "termcap.h"
  12. #include "disp.h"
  13.  
  14. #ifdef    MAC
  15. #    include "mac.h"
  16. #else    /* !MAC */
  17. #    include <sys/stat.h>
  18. #    ifndef    MSDOS
  19. #        include <sys/file.h>
  20. #    else    /* MSDOS */
  21. #        include <fcntl.h>
  22. #        include <io.h>
  23. #    endif    /* MSDOS */
  24. #endif    /* !MAC */
  25.  
  26. #include <errno.h>
  27.  
  28. #ifdef    RAINBOW
  29. private int rbwrite proto((int, char *, int));
  30. #endif
  31.  
  32. #ifndef    L_SET
  33. # define L_SET 0
  34. #endif
  35.  
  36. #define MAXFILES    20    /* good enough for my purposes */
  37.  
  38. private File    openfiles[MAXFILES];    /* must be zeroed initially */
  39.  
  40. File *
  41. fd_open(name, flags, fd, buffer, buf_size)
  42. char    *name,
  43.     *buffer;
  44. int    flags,
  45.     fd,
  46.     buf_size;
  47. {
  48.     register File    *fp;
  49.     register int    i;
  50.  
  51.     for (fp = openfiles, i = 0; i < MAXFILES; i++, fp++)
  52.         if (fp->f_flags == 0)
  53.             break;
  54.     if (i == MAXFILES)
  55.         complain("[Too many open files!]");
  56.     fp->f_bufsize = buf_size;
  57.     fp->f_cnt = 0;
  58.     fp->f_fd = fd;
  59.     fp->f_flags = flags;
  60.     if (buffer == NULL) {
  61.         buffer = emalloc((size_t)buf_size);
  62.         fp->f_flags |= F_MYBUF;
  63.     }
  64.     fp->f_base = fp->f_ptr = buffer;
  65.     fp->f_name = copystr(name);
  66.  
  67.     return fp;
  68. }
  69.  
  70. void
  71. gc_openfiles()
  72. {
  73.     register File    *fp;
  74.  
  75.     for (fp = openfiles; fp < &openfiles[MAXFILES]; fp++)
  76.         if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0)
  77.             f_close(fp);
  78. }
  79.  
  80. File *
  81. f_open(name, flags, buffer, buf_size)
  82. char    *name,
  83.     *buffer;
  84. int    flags,
  85.     buf_size;
  86. {
  87.     register int    fd;
  88.  
  89.     switch (F_MODE(flags)) {
  90.     case F_READ:
  91.         fd = open(name, 0);
  92.         break;
  93.  
  94.     case F_APPEND:
  95.         fd = open(name, 1);
  96.         if (fd != -1) {
  97.             (void) lseek(fd, 0L, 2);
  98.             break;
  99.         }
  100.         /* FALLTHROUGH */
  101.     case F_WRITE:
  102.         fd = creat(name, CreatMode);
  103.         break;
  104.  
  105.     default:
  106.         error("invalid F_MODE");
  107.         /* NOTREACHED */
  108.     }
  109.     if (fd == -1)
  110.         return NULL;
  111. #ifdef    MSDOS
  112.     setmode(fd, 0x8000);
  113. #endif    /* MSDOS */
  114.     return fd_open(name, flags, fd, buffer, buf_size);
  115. }
  116.  
  117. void
  118. f_close(fp)
  119. File    *fp;
  120. {
  121.     if (fp->f_flags & (F_WRITE|F_APPEND)) {
  122.         flushout(fp);
  123. #ifdef    BSD4_2
  124. #ifndef MiNT
  125.         (void) fsync(fp->f_fd);
  126. #endif
  127. #endif
  128.     }
  129.     (void) close(fp->f_fd);
  130.     if (fp->f_flags & F_MYBUF)
  131.         free((UnivPtr) fp->f_base);
  132.     free((UnivPtr) fp->f_name);
  133.     fp->f_flags = 0;    /* indicates that we're available */
  134. }
  135.  
  136. int
  137. filbuf(fp)
  138. File    *fp;
  139. {
  140.     if (fp->f_flags & (F_EOF|F_ERR))
  141.         return EOF;
  142.     fp->f_ptr = fp->f_base;
  143. #ifndef    MSDOS
  144.     do {
  145. #endif    /* MSDOS */
  146.         fp->f_cnt = read(fp->f_fd, (UnivPtr) fp->f_base, (size_t) fp->f_bufsize);
  147. #ifndef    MSDOS
  148.     } while (fp->f_cnt == -1 && errno == EINTR);
  149. #endif    /* MSDOS */
  150.     if (fp->f_cnt == -1) {
  151.         /* I/O error -- treat as EOF */
  152.         writef("[Read error: %s]", strerror(errno));
  153.         fp->f_flags |= F_ERR | F_EOF;
  154.         return EOF;
  155.     }
  156.     if (fp->f_cnt == 0) {
  157.         fp->f_flags |= F_EOF;
  158.         return EOF;
  159.     }
  160.     io_chars += fp->f_cnt;
  161.     return jgetc(fp);
  162. }
  163.  
  164. void
  165. putstr(s)
  166. register char    *s;
  167. {
  168. #ifndef    IBMPC
  169.     register int    c;
  170.  
  171.     while ((c = *s++) != '\0')
  172.         jputchar(c);
  173. #else    /* IBMPC */
  174.     write_emif(s);
  175. #endif    /* IBMPC */
  176. }
  177.  
  178. void
  179. fputnchar(s, n, fp)
  180. register char    *s;
  181. register int    n;
  182. register File    *fp;
  183. {
  184.     while (--n >= 0)
  185.         jputc(*s++, fp);
  186. }
  187.  
  188. void
  189. flushscreen()
  190. {
  191. #ifndef    IBMPC
  192.     flushout(stdout);
  193. #endif    /* IBMPC */
  194. }
  195.  
  196. void
  197. f_seek(fp, offset)
  198. register File    *fp;
  199. off_t    offset;
  200. {
  201.     if (fp->f_flags & (F_WRITE|F_APPEND))
  202.         flushout(fp);
  203.     fp->f_cnt = 0;        /* next read will filbuf(), next write
  204.                    will flush() with no bad effects */
  205.     lseek(fp->f_fd, (long) offset, L_SET);
  206. }
  207.  
  208. void
  209. flushout(fp)
  210. register File    *fp;
  211. {
  212.     register int    n;
  213.  
  214.     if (fp->f_flags & (F_READ | F_STRING | F_ERR)) {
  215.         if (fp->f_flags != F_STRING)
  216.             abort();    /* IMPOSSIBLE */
  217.         /* We just banged into the end of a string.
  218.          * In the interests of continuing, we will cause
  219.          * the rest of the output to be be heaped in the
  220.          * last position.  Surely it will end up as a NUL. UGH!
  221.          */
  222.         fp->f_cnt = 1;
  223.         fp->f_ptr = &fp->f_base[fp->f_bufsize - 1];
  224.         return;
  225.     }
  226.     if (((n = (fp->f_ptr - fp->f_base)) > 0) &&
  227. #ifndef    RAINBOW
  228.         (write(fp->f_fd, (UnivPtr) fp->f_base, (size_t)n) != n) &&
  229. #else
  230.         (rbwrite(fp->f_fd, fp->f_base, n) != n) &&
  231. #endif
  232.         (fp != stdout))
  233.     {
  234.         fp->f_flags |= F_ERR;
  235.         error("[I/O error(%s); file = %s, fd = %d]",
  236.             strerror(errno), fp->f_name, fp->f_fd);
  237.     }
  238.  
  239.     fp->f_cnt = fp->f_bufsize;
  240.     fp->f_ptr = fp->f_base;
  241. }
  242.  
  243. bool
  244. f_gets(fp, buf, max)
  245. register File    *fp;
  246. char    *buf;
  247. size_t    max;
  248. {
  249.     register char    *cp = buf;
  250.     register int    c;
  251.     char    *endp = buf + max - 1;
  252.  
  253.     if (fp->f_flags & F_EOF)
  254.         return YES;
  255.     while (((c = jgetc(fp)) != EOF) && (c != '\n')) {
  256. #ifdef MiNT
  257.         if ((c == '\0') || (c == '\r')) {   /* get rid of ^M */
  258. #else
  259.         if ((c == '\0') {
  260. #endif /* MiNT */
  261.             /* We can't store NUL in our buffer, so ignore it.
  262.              * Of course, with a little ingenuity we could:
  263.              * NUL could be represented by \n!
  264.              */
  265.             continue;
  266.         }
  267.         if (cp >= endp) {
  268.             add_mess(" [Line too long]");
  269.             rbell();
  270.             return YES;
  271.         }
  272.         *cp++ = c;
  273.     }
  274.     *cp = '\0';
  275.     if (c == EOF) {
  276.         if (cp != buf)
  277.             add_mess(" [Incomplete last line]");
  278.         return YES;
  279.     }
  280. #ifdef    MSDOS
  281.     /* a CR followed by a LF is treated as a NL.
  282.      * Bug: the line-buffer is effectively shortened by one character.
  283.      */
  284.     if (cp != buf && cp[-1] == '\r')
  285.         *--cp = '\0';
  286. #endif    /* MSDOS */
  287.     io_lines += 1;
  288.     return NO;    /* this means okay */
  289. }
  290.  
  291. /* skip to beginning of next line, i.e., next read returns first
  292.    character of new line */
  293.  
  294. void
  295. f_toNL(fp)
  296. register File    *fp;
  297. {
  298.     register int    c;
  299.  
  300.     if (fp->f_flags & F_EOF)
  301.         return;
  302.     do ; while (((c = jgetc(fp)) != EOF) && (c != '\n'));
  303.     if (c == EOF)
  304.         fp->f_flags |= F_EOF;
  305. }
  306.  
  307. size_t
  308. f_readn(fp, addr, n)
  309. register File    *fp;
  310. register char    *addr;
  311. size_t    n;
  312. {
  313.     register size_t    nleft;
  314.  
  315.     for (nleft = n; nleft > 0; nleft--) {
  316.         int    c = jgetc(fp);
  317.  
  318.         if (f_eof(fp))
  319.             break;
  320.         *addr++ = c;
  321.     }
  322.     return n - nleft;
  323. }
  324.  
  325. /* Deals with output to the terminal, setting up the amount of characters
  326.    to be buffered depending on the output baud rate.  Why it's in a
  327.    separate file I don't know ... */
  328.  
  329. private char    one_buf;
  330.  
  331. int    BufSize = 1;
  332.  
  333. private File    stdout_File = {1, 1, 1, F_WRITE, &one_buf, &one_buf, (char *)NULL};
  334. File    *stdout = &stdout_File;
  335.  
  336. #ifdef    RAINBOW
  337.  
  338. /*
  339.  * use the Rainbow's video output function
  340.  */
  341.  
  342. #include <dos.h>
  343.  
  344. private int
  345. rbwrite(fd, buf, cnt)
  346. char *buf;
  347. {
  348.     union REGS vr;
  349.  
  350.     if (fd != 1) {
  351.         write(fd, buf, cnt);
  352.     } else {
  353.         while (cnt-- > 0) {
  354.             vr.x.ax = *buf++;
  355.             vr.x.di = 0;
  356.             int86(0x18, &vr, &vr);
  357.         }
  358.     }
  359. }
  360. #endif    /* RAINBOW */
  361.